package com.xstudio.pvzreborn.cmd;

import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.xstudio.pvzreborn.capability.DaveCoin;
import com.xstudio.pvzreborn.capability.PlantFood;
import com.xstudio.pvzreborn.capability.Sunshine;
import com.xstudio.pvzreborn.utils.CapabilityUtils;
import com.xstudio.pvzreborn.utils.PlayerUtils;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.commands.arguments.selector.EntitySelector;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.NotNull;

/**
 * @author Bread_NiceCat
 */
public class PVZCommand {
	public static void init(@NotNull CommandDispatcher<CommandSourceStack> dispatcher) {
		RequiredArgumentBuilder<CommandSourceStack, EntitySelector> editCap = Commands.argument("target", EntityArgument.player())
				.then(Commands.literal("add").then(Commands.argument("value", IntegerArgumentType.integer(1, Integer.MAX_VALUE)).executes(PVZCommand::add)))
				.then(Commands.literal("remove").then(Commands.argument("value", IntegerArgumentType.integer(1, Integer.MAX_VALUE)).executes(PVZCommand::remove)))
				.then(Commands.literal("set").then(Commands.argument("value", IntegerArgumentType.integer()).executes(PVZCommand::set)))
				.then(Commands.literal("get").executes(PVZCommand::get));

		dispatcher.register(Commands.literal("pvzreborn").requires(PVZCommand::reqOpOrUpper)
				.then(Commands.literal(DaveCoin.NAME).then(editCap))
				.then(Commands.literal(Sunshine.NAME).then(editCap))
				.then(Commands.literal(PlantFood.NAME).then(editCap))
		);
	}

	public static int add(@NotNull CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
		ServerPlayer target = getTarget(context);
		String mode = getMode(context);
		int curValue = CapabilityUtils.getEditorByName(mode, target).resolve().get().add(IntegerArgumentType.getInteger(context, "value"), target);
		callback(context, curValue, true);
		return 0;
	}

	public static int remove(@NotNull CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
		String mode = getMode(context);
		ServerPlayer target = getTarget(context);
		int curValue = CapabilityUtils.getEditorByName(mode, target).resolve().get().remove(IntegerArgumentType.getInteger(context, "value"), target);
		callback(context, curValue, true);
		return 0;
	}

	public static int set(@NotNull CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
		String mode = getMode(context);
		ServerPlayer target = getTarget(context);
		int curValue = CapabilityUtils.getEditorByName(mode, target).resolve().get().setValue(IntegerArgumentType.getInteger(context, "value"), target);
		callback(context, curValue, true);
		return 0;
	}

	public static int get(@NotNull CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
		int value = CapabilityUtils.getEditorByName(getMode(context), getTarget(context)).resolve().get().getValue();
		callback(context, value, false);
		return 0;
	}

	/**
	 * @param curValue 当前数值
	 * @param doEdited 是否是编辑模式,if true:发包同步
	 */
	private static void callback(@NotNull CommandContext<CommandSourceStack> context, int curValue, boolean doEdited) throws CommandSyntaxException {
		String mode = getMode(context);
		ServerPlayer player = getTarget(context);
		MutableComponent comp = doEdited ? new TranslatableComponent("command.pvzreborn.edit_successfully") : new TextComponent("");
		comp.append(new TranslatableComponent("command.pvzreborn.query_data", player.getName(), new TranslatableComponent("cap.pvzreborn." + mode).getString(), curValue));
		comp.withStyle(ChatFormatting.GREEN);
		PlayerUtils.sendText(getExecutor(context), comp);
	}

	private static String getMode(@NotNull CommandContext<CommandSourceStack> context) {
		return context.getInput().split(" ", 3)[1];
	}

	private static ServerPlayer getTarget(@NotNull CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
		return EntityArgument.getPlayer(context, "target");
	}

	/**
	 * @return null if 执行者不是玩家
	 */
	private static Player getExecutor(@NotNull CommandContext<CommandSourceStack> context) {
		try {
			return context.getSource().getPlayerOrException();
		} catch (CommandSyntaxException e) {
			return null;
		}
	}

	private static boolean reqOpOrUpper(@NotNull CommandSourceStack sourceStack) {
		return sourceStack.hasPermission(Commands.LEVEL_ADMINS);//3
	}

	private static boolean reqCommandBlockOrUpper(@NotNull CommandSourceStack sourceStack) {
		return sourceStack.hasPermission(Commands.LEVEL_GAMEMASTERS);//2
	}


}
